<template>
    <div class="FlipClock">
        <Flipper ref="flipperHour1" :duration="600" :frontText="0" :backText="0" />
        <Flipper ref="flipperHour2" :duration="600" :frontText="0" :backText="0" />
        <em>:</em>
        <Flipper ref="flipperMinute1" :duration="600" :frontText="0" :backText="0" />
        <Flipper ref="flipperMinute2" :duration="600" :frontText="0" :backText="0" />
        <em>:</em>
        <Flipper ref="flipperSecond1" :duration="600" :frontText="0" :backText="0" />
        <Flipper ref="flipperSecond2" :duration="600" :frontText="0" :backText="0" />
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import Flipper from './unit/Flipper.vue';

const flipperHour1 = ref(null);
const flipperHour2 = ref(null);
const flipperMinute1 = ref(null);
const flipperMinute2 = ref(null);
const flipperSecond1 = ref(null);
const flipperSecond2 = ref(null);

const timer = ref<number | null>(null);
const flipObjs = ref<any[]>([]);

const init = () => {
    const now = new Date();
    const nowTimeStr = formatDate(new Date(now.getTime()), 'hhiiss');
    for (let i = 0; i < flipObjs.value.length; i++) {
        flipObjs.value[i]?.setFront(nowTimeStr[i]);
    }
};

const run = () => {
    timer.value = setInterval(() => {
        const now = new Date();
        const nowTimeStr = formatDate(new Date(now.getTime() - 1000), 'hhiiss');
        const nextTimeStr = formatDate(now, 'hhiiss');
        for (let i = 0; i < flipObjs.value.length; i++) {
            if (nowTimeStr[i] === nextTimeStr[i]) continue;
            flipObjs.value[i]?.flipDown(nowTimeStr[i], nextTimeStr[i]);
        }
    }, 1000);
};

const formatDate = (date: Date, dateFormat: string) => {
    const yearRegex = /(y+)/g;
    let yearMatch;
    while ((yearMatch = yearRegex.exec(dateFormat)) !== null) {
        const yearString = (date.getFullYear() + '').slice(-yearMatch[1].length);
        dateFormat = dateFormat.replace(yearMatch[0], yearString);
    }

    const regexps: { [key: string]: number } = {
        'm+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'i+': date.getMinutes(),
        's+': date.getSeconds()
    };

    for (const k in regexps) {
        const pattern = new RegExp(`(${k})`, 'g');
        dateFormat = dateFormat.replace(pattern, (match, p1) => {
            const value = regexps[k] + '';
            return p1.length > 1 ? padLeftZero(value) : value;
        });
    }
    return dateFormat;
};

const padLeftZero = (str: string) => {
    return ('00' + str).slice(-2);
};

onMounted(() => {
    flipObjs.value = [
        flipperHour1.value,
        flipperHour2.value,
        flipperMinute1.value,
        flipperMinute2.value,
        flipperSecond1.value,
        flipperSecond2.value
    ];
    init();
    run();
});
</script>

<style>
.FlipClock {
    text-align: center;
}

.FlipClock .M-Flipper {
    margin: 0 0.2rem;
}

.FlipClock em {
    user-select: none;
    display: inline-block;
    line-height: 4rem;
    font-size: 3.5rem;
    font-style: normal;
    color: brown;
    vertical-align: top;
}
</style>